/**
 * trouble with select canvas
 * @param id {string}
 * @return {Element}
 */
function getId(id) {
    return document.querySelector("#" + id);
}

/**
 *
 * @param id {string}
 * @return {DOMRect}
 */
function getRect(id) {
    return getId(id).getBoundingClientRect();
}

function currentTime() {
    let current = new Date();
    return {
        day: current.getDate(),
        month: current.getMonth() + 1,
        year: current.getFullYear(),
        hour: current.getHours(),
        minute: current.getMinutes(),
        second: current.getSeconds()
    }
}

function checkTextSize(word, fontSize) {
    let cvs = document.createElement("canvas");
    cvs.style.visibility = "hidden";
    let ctx = cvs.getContext("2d")
    ctx.font = fontSize + "px Arial";
    ctx.textBaseline = "top";
    ctx.fillStyle = "white";
    ctx.fillText(word, 0, 0);
    let imgData = ctx.getImageData(0, 0, cvs.width, cvs.height);
    let startIndex = -1, endIndex = -1;
    for (let i = 0; i < imgData.data.length; i++) {
        if (startIndex === -1 && imgData.data[i] !== 0) {
            startIndex = (i + 4) / 4;
        }
        if (startIndex !== -1 && imgData.data[i] !== 0) {
            endIndex = (i + 1) / 4;
        }
    }
    let firstLine = Math.ceil(startIndex / cvs.width);
    let lastLine = Math.ceil(endIndex / cvs.width);
    let height = lastLine - firstLine;
    let left = startIndex - (firstLine - 1) * cvs.width;
    let width = endIndex - (lastLine - 1) * cvs.width - left;
    cvs.remove();
    return {width: width, height: height};
}

class CanvasDraw {
    constructor(canvasId) {
        this.canvas = document.querySelector("#" + canvasId);
        this.context = this.canvas.getContext("2d");
        this.canWidth = this.canvas.width;
        this.canHeight = this.canvas.height;
        this.center = {x: 0, y: 0};
        this.strokeColor = "black";
        this.fillColor = "white";
        this.shadowBlur = 0;
        this.shadowColor = "black";
    }

    getCenterPoint() {
        this.center.x = this.canWidth / 2;
        this.center.y = this.canHeight / 2;
    }

    setSize(width, height) {
        this.canvas.width = width;
        this.canvas.height = height;
        this.canWidth = this.canvas.width;
        this.canHeight = this.canvas.height;
        this.getCenterPoint();
    }

    /**
     * set draw color and type
     * @param color {string} color
     * @param fill {boolean} which color should be set (stroke or fill color)
     */
    setDrawType(color, fill) {
        if (fill === false) {
            this.strokeColor = color;
            this.context.strokeStyle = this.strokeColor;
            this.context.stroke();
        } else {
            this.fillColor = color;
            this.context.fillStyle = this.fillColor;
            this.context.fill();
        }
    }

    setLineStyle(width) {
        this.context.lineWidth = width;
    }

    setShadow(blur, color) {
        this.shadowBlur = blur;
        this.context.shadowBlur = this.shadowBlur;
        this.shadowColor = color;
        this.context.shadowColor = this.shadowColor;
    }

    setText(align, baseline) {
        let alignArray = ["start", "end", "left", "center", "right"];
        this.context.textAlign = alignArray[align];
        let baseArray = ["top", "bottom", "middle", "alphabetic", "hanging"];
        this.context.textBaseline = baseArray[baseline];
    }

    /**
     * set solid background
     * @param color {string}
     */
    setSolidBackground(color) {
        this.context.beginPath();
        this.context.fillStyle = color;
        this.context.rect(0, 0, this.canWidth, this.canHeight);
        this.setDrawType(color, true);
    }

    drawCircle(x, y, r, color, fill) {
        this.context.beginPath();
        this.context.arc(x, y, r, 0, 2 * Math.PI);
        this.setDrawType(color, fill);
    }

    drawText(text, x, y, fontSize, fontName, color) {
        this.context.beginPath();
        this.context.fillStyle = color;
        this.context.font = fontSize + "px " + fontName;
        this.context.fillText(text, x, y);
    }

}

function showTime(draw, x, y) {
    let hh = currentTime().hour < 10 ? "0" + currentTime().hour : currentTime().hour;
    let mm = currentTime().minute < 10 ? "0" + currentTime().minute : currentTime().minute;
    let ss = currentTime().second < 10 ? "0" + currentTime().second : currentTime().second;
    let fontSize = 40;
    let size = checkTextSize("H", fontSize);
    let time = hh + ":" + mm + ":" + ss;
    draw.setText(2, 1);
    draw.context.save();
    draw.context.translate(x, y);
    for (let i = 0; i < time.length; i++) {
        draw.drawText(time[i], (i - time.length / 2) * (size.width+2), size.height / 2, fontSize, "Arial", "white");
    }
    draw.context.restore();
}

function refresh() {
    let docRect = getRect("container");
    let draw = new CanvasDraw("canvas");
    draw.setSize(docRect.width, docRect.height);
    draw.setSolidBackground("black");
    draw.setLineStyle(10);
    draw.setShadow(15, "#00ffff");
    draw.drawCircle(draw.center.x, draw.center.y, 150, "rgba(255,255,255,0.8)", false);
    draw.setText(3, 2);
    let time = currentTime();
    draw.setShadow(0, "#00ffff");
    showTime(draw, draw.center.x, draw.center.y);
}

window.onload = function () {
    let start, previousTimeStamp;
    let done = false

    function step(timestamp) {
        if (start === undefined) {
            start = timestamp;
        }
        const elapsed = timestamp - start;

        if (previousTimeStamp !== timestamp) {
            refresh();
        }

        if (elapsed > -1) {
            previousTimeStamp = timestamp;
            if (!done) {
                window.requestAnimationFrame(step);
            }
        }
    }

    window.requestAnimationFrame(step);
}